#include "mixp_config.h"
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <errno.h>

extern struct mixp_config_ops mixp_json_ops;

struct mixp_config *g_config = NULL;

struct config_ops_list
{
    char suffix[32];
    struct mixp_config_ops *ops;
};

static struct config_ops_list conf_ops_list[] = {
    {"json", &mixp_json_ops}};

static char *get_file_suffix(const char *name)
{
    int point = '.';
    char *tmp = strrchr((char *)name, point);
    if (tmp)
    {
        return tmp + 1;
    }
    return NULL;
}

static struct mixp_config_ops *find_backend(const char *name)
{
    int i = 0;
    int max_list;
    char *suffix;
    if (!name)
    {
        printf("config name can not be NULL\n");
        return NULL;
    }
    max_list = sizeof(conf_ops_list) / sizeof(conf_ops_list[0]);
    suffix = get_file_suffix(name);
    if (!suffix)
    {
        printf("there is no suffix in config name\n");
        return NULL;
    }
    for (i = 0; i < max_list; i++)
    {
        if (!strcasecmp(conf_ops_list[i].suffix, suffix))
        {
            break;
        }
    }
    if (i == max_list)
    {
        printf("the %s file is not supported\n", suffix);
        return NULL;
    }
    return conf_ops_list[i].ops;
}

struct mixp_config *mixp_conf_load(const char *name)
{
    struct mixp_config *c;
    struct mixp_config_ops *ops = find_backend(name);
    if (!ops)
    {
        printf("can not find valid config backend\n");
        return NULL;
    }
    c = (struct mixp_config *)calloc(1, sizeof(struct mixp_config));
    if (!c)
    {
        printf("malloc failed!\n");
        return NULL;
    }
    c->ops = ops;
    if (c->ops->load)
    {
        if (-1 == c->ops->load(c, name))
        {
            free(c);
            return NULL;
        }
    }
    g_config = c;
    return c;
}

void mixp_conf_unload(struct mixp_config *c)
{
    if (c && c->ops->unload)
    {
        c->ops->unload(c);
    }
    free(c);
}
